/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>
#include <vector>

#include "hks_access_control_rsa_sign_verify_test_common.h"

using namespace testing::ext;
namespace Unittest::AccessControlRsaSignVerify {

int32_t RSAAuthTokenSign(struct HksBlob *challenge, uint64_t secureUid, uint64_t enrolledId, uint64_t time, struct HksParam *tmpParams) {
    std::vector<uint8_t> token;
    // 添加authtoken
    int32_t ret = HksAccessControlPartTest::AuthTokenSign(challenge, secureUid, enrolledId, time, token);
    if (ret != HKS_SUCCESS) {
        HKS_LOG_E("AuthTokenSign Failed.");
        return ret;
    }
    uint8_t authToken[AUTH_TOKEN_LEN] = {0};
    for (int i = 0; i < AUTH_TOKEN_LEN; i++) {
        authToken[i] = token[i];
    }
    tmpParams->tag = HKS_TAG_AUTH_TOKEN;
    tmpParams->blob.data = authToken;
    tmpParams->blob.size = AUTH_TOKEN_LEN;
    return HKS_SUCCESS;
}

int32_t AddAuthTokenParam(struct HksParamSet *paramSet, const struct HksParam *tmpParams) {
    int32_t ret = HksAddParams(paramSet, tmpParams, 1);
    if (ret != HKS_SUCCESS) {
        HKS_LOG_E("HksAddParam failed!\n");
        return ret;
    }
    ret = HksBuildParamSet(&paramSet);
    if (ret != HKS_SUCCESS) {
        HKS_LOG_E("HksBuildParamSet failed!\n");
        return ret;
    }
    return HKS_SUCCESS;
}

int32_t HksAcRsaSignVerifyTestNormalCase(const TestAccessCaseRSAParams &testCaseParams, uint64_t secureUid, uint64_t enrolledId, uint64_t time)
{
    struct HksBlob inData = { g_inData.length(), (uint8_t *)g_inData.c_str() };
    uint8_t tmpIn[] = "tempIn";
    struct HksBlob finishInData = { 0, tmpIn };
    int32_t ret = HKS_FAILURE;

    /* 1. Generate Key */
    // Generate Key
    struct HksParamSet *genParamSet = nullptr;
    ret = InitParamSet(&genParamSet, testCaseParams.genParams.data(), testCaseParams.genParams.size());
    EXPECT_EQ(ret, HKS_SUCCESS) << "InitgenParamSet failed.";
    uint8_t alias[] = "AcRSASignVerify";
    struct HksBlob keyAlias = { sizeof(alias), alias };
    ret = HksGenerateKey(&keyAlias, genParamSet, nullptr);
    EXPECT_EQ(ret, HKS_SUCCESS) << "RSA generate key failed.";
    
    /* 2. Sign Three Stage */
    // Init
    struct HksParamSet *signParamSet = nullptr;
    ret = InitParamSet(&signParamSet, testCaseParams.signParams.data(), testCaseParams.signParams.size());
    EXPECT_EQ(ret, HKS_SUCCESS) << "InitsignParamSet failed.";
    
    uint8_t handleS[sizeof(uint64_t)] = {0};
    struct HksBlob handleSign = { sizeof(uint64_t), handleS };
    uint8_t challengeSign[sizeof(uint64_t)] = {0};
    struct HksBlob challengeSignBlob = { sizeof(uint64_t), challengeSign };
    ret = HksInit(&keyAlias, signParamSet, &handleSign, &challengeSignBlob);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Init failed.";

    // Update loop
    struct HksParam signParams;
    ret = RSAAuthTokenSign(&challengeSignBlob, secureUid, enrolledId, time, &signParams);
    EXPECT_EQ(ret, HKS_SUCCESS) << "AuthToken sign failed.";
    ret = AddAuthTokenParam(signParamSet, &signParams);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Add Param failed.";
    ret = HksTestUpdate(&handleSign, signParamSet, &inData);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Update failed.";

    // Finish
    uint8_t outDataS[RSA_COMMON_SIZE] = {0};
    struct HksBlob outDataSign = { RSA_COMMON_SIZE, outDataS };
    ret = HksFinish(&handleSign, signParamSet, &finishInData, &outDataSign);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Finish failed.";

    /* 3. Export Public Key */
    uint8_t pubKey[HKS_RSA_KEY_SIZE_1024] = {0};
    struct HksBlob publicKey = { HKS_RSA_KEY_SIZE_1024, pubKey };
    ret = HksExportPublicKey(&keyAlias, genParamSet, &publicKey);
    EXPECT_EQ(ret, HKS_SUCCESS) << "ExportPublicKey failed.";

    /* 4. Import Key */
    struct HksParamSet *verifyParamSet = nullptr;
    ret = InitParamSet(&verifyParamSet, testCaseParams.verifyParams.data(), testCaseParams.verifyParams.size());
    EXPECT_EQ(ret, HKS_SUCCESS) << "InitverifyParamSet failed.";

    char newKey[] = "RSA_Sign_Verify_Import_KeyAlias";
    struct HksBlob newKeyAlias = { .size = strlen(newKey), .data = (uint8_t *)newKey };
    ret = HksImportKey(&newKeyAlias, verifyParamSet, &publicKey);
    EXPECT_EQ(ret, HKS_SUCCESS) << "ImportKey failed";

    /* 5. Verify Three Stage */
    // Init
    uint8_t handleV[sizeof(uint64_t)] = {0};
    struct HksBlob handleVerify = { sizeof(uint64_t), handleV };
    uint8_t challengeVerify[sizeof(uint64_t)] = {0};
    struct HksBlob challengeVerifyBlob = { sizeof(uint64_t), challengeVerify };
    ret = HksInit(&newKeyAlias, verifyParamSet, &handleVerify, &challengeVerifyBlob);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Init failed.";
    // Update loop
    struct HksParam verifyParams;
    ret = RSAAuthTokenSign(&challengeVerifyBlob, secureUid, enrolledId, time, &verifyParams);
    EXPECT_EQ(ret, HKS_SUCCESS) << "AuthToken sign failed.";
    ret = AddAuthTokenParam(verifyParamSet, &verifyParams);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Add Param failed.";
    ret = HksTestUpdate(&handleSign, verifyParamSet, &inData);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Update failed.";
    // Finish
    uint8_t temp[] = "out";
    struct HksBlob verifyOut = { sizeof(temp), temp };
    ret = HksFinish(&handleVerify, verifyParamSet, &outDataSign, &verifyOut);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Finish failed.";

    /* 6. Delete New Key */
    int32_t deleteRet = HksDeleteKey(&newKeyAlias, verifyParamSet);
    EXPECT_EQ(deleteRet, HKS_SUCCESS) << "Delete ImportKey failed.";
    
    ret = HksDeleteKey(&keyAlias, genParamSet);
    EXPECT_EQ(ret, HKS_SUCCESS) << "DeleteKey failed.";

    HksFreeParamSet(&genParamSet);
    HksFreeParamSet(&signParamSet);
    HksFreeParamSet(&verifyParamSet);

    return ret;
}

int32_t HksAcRsaSignVerifyTestAbnormalCase(const TestAccessCaseRSAParams &testCaseParams, uint64_t secureUid, uint64_t enrolledId, uint64_t time)
{
    struct HksBlob inData = { g_inData.length(), (uint8_t *)g_inData.c_str() };
    uint8_t tmpIn[] = "tempIn";
    struct HksBlob finishInData = { 0, tmpIn };
    int32_t ret = HKS_FAILURE;

    /* 1. Generate Key */
    // Generate Key
    struct HksParamSet *genParamSet = nullptr;
    ret = InitParamSet(&genParamSet, testCaseParams.genParams.data(), testCaseParams.genParams.size());
    EXPECT_EQ(ret, HKS_SUCCESS) << "InitgenParamSet failed.";
    uint8_t alias[] = "AcRSASignVerify";
    struct HksBlob keyAlias = { sizeof(alias), alias };
    ret = HksGenerateKey(&keyAlias, genParamSet, nullptr);
    EXPECT_EQ(ret, HKS_SUCCESS) << "RSA generate key failed.";
    
    /* 2. Sign Three Stage */
    // Init
    struct HksParamSet *signParamSet = nullptr;
    ret = InitParamSet(&signParamSet, testCaseParams.signParams.data(), testCaseParams.signParams.size());
    EXPECT_EQ(ret, HKS_SUCCESS) << "InitsignParamSet failed.";
    
    uint8_t handleS[sizeof(uint64_t)] = {0};
    struct HksBlob handleSign = { sizeof(uint64_t), handleS };
    uint8_t challengeSign[sizeof(uint64_t)] = {0};
    struct HksBlob challengeSignBlob = { sizeof(uint64_t), challengeSign };
    ret = HksInit(&keyAlias, signParamSet, &handleSign, &challengeSignBlob);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Init failed.";

    // Update loop
    struct HksParam signParams;
    ret = RSAAuthTokenSign(&challengeSignBlob, secureUid, enrolledId, time, &signParams);
    EXPECT_EQ(ret, HKS_SUCCESS) << "AuthToken sign failed.";
    ret = AddAuthTokenParam(signParamSet, &signParams);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Add Param failed.";
    ret = HksTestUpdate(&handleSign, signParamSet, &inData);
    EXPECT_NE(ret, HKS_SUCCESS) << "Update failed.";

    // Finish
    uint8_t outDataS[RSA_COMMON_SIZE] = {0};
    struct HksBlob outDataSign = { RSA_COMMON_SIZE, outDataS };
    ret = HksFinish(&handleSign, signParamSet, &finishInData, &outDataSign);
    EXPECT_NE(ret, HKS_SUCCESS) << "Finish failed.";

    /* 3. Export Public Key */
    uint8_t pubKey[HKS_RSA_KEY_SIZE_1024] = {0};
    struct HksBlob publicKey = { HKS_RSA_KEY_SIZE_1024, pubKey };
    ret = HksExportPublicKey(&keyAlias, genParamSet, &publicKey);
    EXPECT_EQ(ret, HKS_SUCCESS) << "ExportPublicKey failed.";

    /* 4. Import Key */
    struct HksParamSet *verifyParamSet = nullptr;
    ret = InitParamSet(&verifyParamSet, testCaseParams.verifyParams.data(), testCaseParams.verifyParams.size());
    EXPECT_EQ(ret, HKS_SUCCESS) << "InitverifyParamSet failed.";

    char newKey[] = "RSA_Sign_Verify_Import_KeyAlias";
    struct HksBlob newKeyAlias = { .size = strlen(newKey), .data = (uint8_t *)newKey };
    ret = HksImportKey(&newKeyAlias, verifyParamSet, &publicKey);
    EXPECT_EQ(ret, HKS_SUCCESS) << "ImportKey failed";

    /* 5. Verify Three Stage */
    // Init
    uint8_t handleV[sizeof(uint64_t)] = {0};
    struct HksBlob handleVerify = { sizeof(uint64_t), handleV };
    uint8_t challengeVerify[sizeof(uint64_t)] = {0};
    struct HksBlob challengeVerifyBlob = { sizeof(uint64_t), challengeVerify };
    ret = HksInit(&newKeyAlias, verifyParamSet, &handleVerify, &challengeVerifyBlob);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Init failed.";
    // Update loop
    struct HksParam verifyParams;
    ret = RSAAuthTokenSign(&challengeVerifyBlob, secureUid, enrolledId, time, &verifyParams);
    EXPECT_EQ(ret, HKS_SUCCESS) << "AuthToken sign failed.";
    ret = AddAuthTokenParam(verifyParamSet, &verifyParams);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Add Param failed.";
    ret = HksTestUpdate(&handleSign, verifyParamSet, &inData);
    EXPECT_NE(ret, HKS_SUCCESS) << "Update failed.";
    // Finish
    uint8_t temp[] = "out";
    struct HksBlob verifyOut = { sizeof(temp), temp };
    ret = HksFinish(&handleVerify, verifyParamSet, &outDataSign, &verifyOut);
    EXPECT_NE(ret, HKS_SUCCESS) << "Finish failed.";

    /* 6. Delete New Key */
    int32_t deleteRet = HksDeleteKey(&newKeyAlias, verifyParamSet);
    EXPECT_EQ(deleteRet, HKS_SUCCESS) << "Delete ImportKey failed.";
    
    ret = HksDeleteKey(&keyAlias, genParamSet);
    EXPECT_EQ(ret, HKS_SUCCESS) << "DeleteKey failed.";

    HksFreeParamSet(&genParamSet);
    HksFreeParamSet(&signParamSet);
    HksFreeParamSet(&verifyParamSet);

    return ret;
}

int32_t HksAcRsaSignVerifyTestCustomCase(const TestAccessCaseRSAParams &testCaseParams1, const TestAccessCaseRSAParams &testCaseParams2, 
    uint64_t secureUid, uint64_t enrolledId, uint64_t time)
{
    struct HksBlob inData = { g_inData.length(), (uint8_t *)g_inData.c_str() };
    int32_t ret = HKS_FAILURE;

    /* 1. Generate Key */
    // Generate Key
    struct HksParamSet *genParamSet1 = nullptr;
    ret = InitParamSet(&genParamSet1, testCaseParams1.genParams.data(), testCaseParams1.genParams.size());
    EXPECT_EQ(ret, HKS_SUCCESS) << "InitgenParamSet failed.";
    uint8_t alias1[] = "Ac_RSA_Sign_Verify1";
    struct HksBlob keyAlias1 = { sizeof(alias1), alias1 };
    ret = HksGenerateKey(&keyAlias1, genParamSet1, nullptr);
    EXPECT_EQ(ret, HKS_SUCCESS) << "RSA generate key failed.";

    struct HksParamSet *genParamSet2 = nullptr;
    ret = InitParamSet(&genParamSet2, testCaseParams2.genParams.data(), testCaseParams2.genParams.size());
    EXPECT_EQ(ret, HKS_SUCCESS) << "InitgenParamSet failed.";
    uint8_t alias2[] = "Ac_RSA_Sign_Verify2";
    struct HksBlob keyAlias2 = { sizeof(alias2), alias2 };
    ret = HksGenerateKey(&keyAlias2, genParamSet2, nullptr);
    EXPECT_EQ(ret, HKS_SUCCESS) << "RSA generate key failed.";

    /* 2. Sign Three Stage */
    // Init
    struct HksParamSet *signParamSet1 = nullptr;
    ret = InitParamSet(&signParamSet1, testCaseParams1.signParams.data(), testCaseParams1.signParams.size());
    EXPECT_EQ(ret, HKS_SUCCESS) << "InitsignParamSet failed.";
    uint8_t handleS1[sizeof(uint64_t)] = {0};
    struct HksBlob handleSign1 = { sizeof(uint64_t), handleS1 };
    uint8_t challengeSign1[sizeof(uint64_t)] = {0};
    struct HksBlob challengeSignBlob1 = { sizeof(uint64_t), challengeSign1 };
    ret = HksInit(&keyAlias1, signParamSet1, &handleSign1, &challengeSignBlob1);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Init failed.";
    
    struct HksParamSet *signParamSet2 = nullptr;
    ret = InitParamSet(&signParamSet2, testCaseParams2.signParams.data(), testCaseParams2.signParams.size());
    EXPECT_EQ(ret, HKS_SUCCESS) << "InitsignParamSet failed.";
    uint8_t handleS2[sizeof(uint64_t)] = {0};
    struct HksBlob handleSign2 = { sizeof(uint64_t), handleS2 };
    uint8_t challengeSign2[sizeof(uint64_t)] = {0};
    struct HksBlob challengeSignBlob2 = { sizeof(uint64_t), challengeSign2 };
    ret = HksInit(&keyAlias2, signParamSet2, &handleSign2, &challengeSignBlob2);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Init failed.";

    // Update loop
    struct HksParam signParams;
    uint8_t challengeSign[sizeof(uint64_t)*2] = {0};
    struct HksBlob challengeSignBlob = { sizeof(uint64_t)*2, challengeSign };
    if (memcpy_s(challengeSignBlob.data, sizeof(uint64_t), challengeSignBlob1.data, challengeSignBlob1.size) != EOK) {
        return HKS_FAILURE;
    }
    if (memcpy_s(challengeSignBlob.data + sizeof(uint64_t), sizeof(uint64_t), challengeSignBlob2.data, challengeSignBlob2.size) != EOK) {
        return HKS_FAILURE;
    }
    ret = RSAAuthTokenSign(&challengeSignBlob, secureUid, enrolledId, time, &signParams);
    EXPECT_EQ(ret, HKS_SUCCESS) << "AuthToken sign failed.";
    ret = AddAuthTokenParam(signParamSet1, &signParams);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Add Param failed.";
    struct HksParam challengePos1;
    challengePos1.tag = HKS_TAG_CHALLENGE_POS;
    challengePos1.uint32Param = HKS_CHALLENGE_POS_0;
    ret = AddAuthTokenParam(signParamSet1, &challengePos1);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Add Param failed.";
    ret = HksTestUpdate(&handleSign1, signParamSet1, &inData);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Update failed.";

    ret = AddAuthTokenParam(signParamSet2, &signParams);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Add Param failed.";
    struct HksParam challengePos2;
    challengePos2.tag = HKS_TAG_CHALLENGE_POS;
    challengePos2.uint32Param = HKS_CHALLENGE_POS_1;
    ret = AddAuthTokenParam(signParamSet2, &challengePos2);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Add Param failed.";
    ret = HksTestUpdate(&handleSign2, signParamSet2, &inData);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Update failed.";

    // Finish
    uint8_t tmpIn1[] = "tempIn";
    struct HksBlob finishInData1 = { 0, tmpIn1 };
    uint8_t outDataS1[RSA_COMMON_SIZE] = {0};
    struct HksBlob outDataSign1 = { RSA_COMMON_SIZE, outDataS1 };
    ret = HksFinish(&handleSign1, signParamSet1, &finishInData1, &outDataSign1);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Finish failed.";

    uint8_t tmpIn2[] = "tempIn";
    struct HksBlob finishInData2 = { 0, tmpIn2 };
    uint8_t outDataS2[RSA_COMMON_SIZE] = {0};
    struct HksBlob outDataSign2 = { RSA_COMMON_SIZE, outDataS2 };
    ret = HksFinish(&handleSign2, signParamSet2, &finishInData2, &outDataSign2);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Finish failed.";

    /* 3. Export Public Key */
    uint8_t pubKey1[HKS_RSA_KEY_SIZE_1024] = {0};
    struct HksBlob publicKey1 = { HKS_RSA_KEY_SIZE_1024, pubKey1 };
    ret = HksExportPublicKey(&keyAlias1, genParamSet1, &publicKey1);
    EXPECT_EQ(ret, HKS_SUCCESS) << "ExportPublicKey failed.";

    uint8_t pubKey2[HKS_RSA_KEY_SIZE_1024] = {0};
    struct HksBlob publicKey2 = { HKS_RSA_KEY_SIZE_1024, pubKey2 };
    ret = HksExportPublicKey(&keyAlias2, genParamSet2, &publicKey2);
    EXPECT_EQ(ret, HKS_SUCCESS) << "ExportPublicKey failed.";

    /* 4. Import Key */
    struct HksParamSet *verifyParamSet1 = nullptr;
    ret = InitParamSet(&verifyParamSet1, testCaseParams1.verifyParams.data(), testCaseParams1.verifyParams.size());
    EXPECT_EQ(ret, HKS_SUCCESS) << "InitverifyParamSet failed.";
    char newKey1[] = "RSA_Sign_Verify_Import_KeyAlia1";
    struct HksBlob newKeyAlias1 = { .size = strlen(newKey1), .data = (uint8_t *)newKey1 };
    ret = HksImportKey(&newKeyAlias1, verifyParamSet1, &publicKey1);
    EXPECT_EQ(ret, HKS_SUCCESS) << "ImportKey failed";

    struct HksParamSet *verifyParamSet2 = nullptr;
    ret = InitParamSet(&verifyParamSet2, testCaseParams2.verifyParams.data(), testCaseParams2.verifyParams.size());
    EXPECT_EQ(ret, HKS_SUCCESS) << "InitverifyParamSet failed.";
    char newKey2[] = "RSA_Sign_Verify_Import_KeyAlia2";
    struct HksBlob newKeyAlias2 = { .size = strlen(newKey2), .data = (uint8_t *)newKey2 };
    ret = HksImportKey(&newKeyAlias2, verifyParamSet2, &publicKey2);
    EXPECT_EQ(ret, HKS_SUCCESS) << "ImportKey failed";

    /* 5. Verify Three Stage */
    // Init
    uint8_t handleV1[sizeof(uint64_t)] = {0};
    struct HksBlob handleVerify1 = { sizeof(uint64_t), handleV1 };
    uint8_t challengeVerify1[sizeof(uint64_t)] = {0};
    struct HksBlob challengeVerifyBlob1 = { sizeof(uint64_t), challengeVerify1 };
    ret = HksInit(&newKeyAlias2, verifyParamSet1, &handleVerify1, &challengeVerifyBlob1);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Init failed.";

    uint8_t handleV2[sizeof(uint64_t)] = {0};
    struct HksBlob handleVerify2 = { sizeof(uint64_t), handleV2 };
    uint8_t challengeVerify2[sizeof(uint64_t)] = {0};
    struct HksBlob challengeVerifyBlob2 = { sizeof(uint64_t), challengeVerify2 };
    ret = HksInit(&newKeyAlias2, verifyParamSet2, &handleVerify2, &challengeVerifyBlob2);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Init failed.";
    // Update loop
    struct HksParam verifyParams;
    uint8_t challengeVerify[sizeof(uint64_t)*2] = {0};
    struct HksBlob challengeVerifyBlob = { sizeof(uint64_t)*2,  challengeVerify };
    if (memcpy_s(challengeVerifyBlob.data, sizeof(uint64_t), challengeVerifyBlob1.data, challengeVerifyBlob1.size) != EOK) {
        return HKS_FAILURE;
    }
    if (memcpy_s(challengeVerifyBlob.data + sizeof(uint64_t), sizeof(uint64_t), challengeVerifyBlob2.data, challengeVerifyBlob2.size) != EOK) {
        return HKS_FAILURE;
    }
    ret = RSAAuthTokenSign(&challengeVerifyBlob, secureUid, enrolledId, time, &verifyParams);
    EXPECT_EQ(ret, HKS_SUCCESS) << "AuthToken sign failed.";
    ret = AddAuthTokenParam(verifyParamSet1, &verifyParams);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Add Param failed.";
    ret = AddAuthTokenParam(verifyParamSet1, &challengePos1);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Add Param failed.";
    ret = HksTestUpdate(&handleVerify1, verifyParamSet1, &inData);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Update failed.";

    ret = AddAuthTokenParam(verifyParamSet2, &verifyParams);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Add Param failed.";
    ret = AddAuthTokenParam(verifyParamSet2, &challengePos2);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Add Param failed.";
    ret = HksTestUpdate(&handleVerify2, verifyParamSet2, &inData);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Update failed.";
    // Finish
    uint8_t temp1[] = "out";
    struct HksBlob verifyOut1 = { sizeof(temp1), temp1 };
    ret = HksFinish(&handleVerify1, verifyParamSet1, &outDataSign1, &verifyOut1);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Finish failed.";

    uint8_t temp2[] = "out";
    struct HksBlob verifyOut2 = { sizeof(temp2), temp2 };
    ret = HksFinish(&handleVerify2, verifyParamSet2, &outDataSign2, &verifyOut2);
    EXPECT_EQ(ret, HKS_SUCCESS) << "Finish failed.";

    /* 6. Delete New Key */
    int32_t deleteRet = HksDeleteKey(&newKeyAlias1, verifyParamSet1);
    EXPECT_EQ(deleteRet, HKS_SUCCESS) << "Delete ImportKey failed.";
    deleteRet = HksDeleteKey(&newKeyAlias2, verifyParamSet2);
    EXPECT_EQ(deleteRet, HKS_SUCCESS) << "Delete ImportKey failed.";

    ret = HksDeleteKey(&keyAlias1, genParamSet1);
    EXPECT_EQ(ret, HKS_SUCCESS) << "DeleteKey failed.";
    ret = HksDeleteKey(&keyAlias2, genParamSet2);
    EXPECT_EQ(ret, HKS_SUCCESS) << "DeleteKey failed.";

    HksFreeParamSet(&genParamSet1);
    HksFreeParamSet(&signParamSet1);
    HksFreeParamSet(&verifyParamSet1);
    HksFreeParamSet(&genParamSet2);
    HksFreeParamSet(&signParamSet2);
    HksFreeParamSet(&verifyParamSet2);

    return ret;
}
}